%%%-------------------------------------------------------------------
%%% @author liuwentao
%%% @doc
%%%      单位进程
%%% @end
%%% Created : 26. 7月 2021 16:19
%%%-------------------------------------------------------------------
-module(unit).
-author("liuwentao").

-behaviour(gen_statem).

%% API
-export([
    create/2                    %% 创建单位
]).

%% gen_statem callbacks
-export([init/1, format_status/2, state_name/3, handle_event/4, terminate/3,
    code_change/4, callback_mode/0]).

-define(SERVER, ?MODULE).
-include("unit.hrl").
-include("common.hrl").
-include("pos.hrl").
-include("timer.hrl").


%%%===================================================================
%%% API
%%%===================================================================

start_link(Unit) ->
    gen_statem:start_link({local, ?SERVER}, ?MODULE, [Unit], []).

%%%===================================================================
%%% gen_statem callbacks
%%%===================================================================

init([Unit = #unit{pos = Pos = #pos{map = MapId}, def_status = DefStatus, t_move = Tmove, name = Name}]) ->
    %% 获取时间点
    Ts = erlang:timestamp(),
    Unit1 = Unit#unit{pid = self(), ts = Ts},
    %% 装换为地图单位
    {ok, MapUnit} = unit_convert:to(map_unit, Unit1),
    %% 进入地图
    case map:unit_enter(MapId, MapUnit) of
        {ok, MapBaseId, MapPid, GridPid} ->
            process_flag(trap_exit, true),
            %% @todo 初始化单位AI
            %% 处理单位位置
            NewUnit = Unit1#unit{pos = Pos#pos{map_pid = MapPid, map_base_id = MapBaseId, map_grid_pid = GridPid}},
            %% 保存信息
            unit_mgr:insert(NewUnit),
            %% 根据默认状态设置状态切换定时器
            case DefStatus of
                move ->
                    {ok, DefStatus, NewUnit, util:time_left(Tmove, Ts)};
                load ->
                    {ok, DefStatus, NewUnit, util:time_left(Tmove, Ts)};
                _ ->
                    {ok, DefStatus, NewUnit}
            end;
        _E ->
            ?ERR("单位[~ts]进入地图[~ts]失败:why~w", [Name, MapId, _E]),
            {stop, normal, Unit1}
    end.

callback_mode() ->
    %% 回调回各个状态的函数
    state_functions.

format_status(_Opt, [_PDict, _StateName, _State]) ->
    Status = some_term,
    Status.

state_name(_EventType, _EventContent, State = #unit{}) ->
    NextStateName = next_state,
    {next_state, NextStateName, State}.

handle_event(_EventType, _EventContent, StateName, State = #unit{}) ->
    {next_state, StateName, State}.

terminate(_Reason, _StateName, _State = #unit{}) ->
    ok.

code_change(_OldVsn, StateName, State = #unit{}, _Extra) ->
    {ok, StateName, State}.

%%%===================================================================
%%% Internal functions
%%%===================================================================
%% @doc 创建单位
create({BattleId, Id}, Unit = #unit{name = Name}) ->
    case unit_mgr:info({BattleId, Id}) of
        {ok, _} ->
            ?ERR("地图[~w]创建单位[~ts]ID[~w]重复错误", [BattleId, Name, Id]),
            {error, repeat};
        _ ->
            %% 给单位id赋值
            NewUnit = Unit#unit{id = {BattleId, Id}},
            case start_link(NewUnit) of
                {ok, Pid} -> {ok, NewUnit#unit{pid =Pid}};
                _ -> {error, wrong}
            end
    end.

%% @doc 状态超时计算
continue(move, Reply, State = #unit{ts = Ts, t_move = Tmove}) ->
    {reply, Reply, move, State, util:time_left(Tmove, Ts)}.

